package com.example.app.sharescreen;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.app.R;

import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaStream;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;

public class ShareScreen extends AppCompatActivity implements 
        WebSocketManager.WebSocketCallback,
        PeerConnectionManager.PeerConnectionCallback,
        ScreenCaptureManager.ScreenCaptureCallback,
        PermissionManager.PermissionCallback {
    
    private static final String TAG = "ShareScreen";
    
    // UI components
    private SurfaceViewRenderer localVideoView;
    private SurfaceViewRenderer remoteVideoView;
    private EditText etToUser;
    private Button btnCall;
    
    // Managers
    private UserSessionManager userSessionManager;
    private WebSocketManager webSocketManager;
    private PeerConnectionManager peerConnectionManager;
    private ScreenCaptureManager screenCaptureManager;
    private PermissionManager permissionManager;
    
    // WebRTC components
    private EglBase eglBase;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sharescreen);
        initViews();
        initManagers();
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            permissionManager.checkAndRequestPermissions();
        } else {
            initWebSocket();
            showUsernameToast();
        }
    }
    
    private void initViews() {
        localVideoView = findViewById(R.id.local_video);
        remoteVideoView = findViewById(R.id.remote_video);
        etToUser = findViewById(R.id.et_to_user);
        btnCall = findViewById(R.id.btn_call);
        Button btnHangup = findViewById(R.id.btn_hangup);
        
        btnCall.setOnClickListener(v -> startCall());
        btnHangup.setOnClickListener(v -> hangup());
    }
    
    private void initManagers() {
        // Initialize EglBase
        eglBase = EglBase.create();
        
        // Initialize managers
        userSessionManager = new UserSessionManager();
        webSocketManager = new WebSocketManager(userSessionManager.getUsername(), this);
        peerConnectionManager = new PeerConnectionManager(this, eglBase, this);
        screenCaptureManager = new ScreenCaptureManager(this, this);
        permissionManager = new PermissionManager(this, this);
        
        // Initialize WebRTC views
        localVideoView.init(eglBase.getEglBaseContext(), null);
        remoteVideoView.init(eglBase.getEglBaseContext(), null);
    }
    
    private void initWebSocket() {
        try {
            webSocketManager.connect();
        } catch (Exception e) {
            Log.e(TAG, "Error initializing WebSocket: " + e.getMessage());
            Toast.makeText(this, "连接服务器失败", Toast.LENGTH_SHORT).show();
        }
    }
    
    private void startCall() {
        String targetUser = etToUser.getText().toString();
        if (targetUser.isEmpty()) {
            Toast.makeText(this, "请输入目标用户ID", Toast.LENGTH_SHORT).show();
            return;
        }
        
        userSessionManager.setTargetUser(targetUser);
        userSessionManager.setIsCaller(true);
        
        peerConnectionManager.createPeerConnection();
        screenCaptureManager.requestScreenCapture();
        webSocketManager.sendCallStart(targetUser);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        screenCaptureManager.handleActivityResult(requestCode, resultCode, data);
    }
    
    // PermissionManager.PermissionCallback methods
    @Override
    public void onPermissionsGranted() {
        initWebSocket();
        showUsernameToast();
    }
    
    @Override
    public void onPermissionsDenied(boolean criticalPermissionDenied) {
        if (!criticalPermissionDenied) {
            initWebSocket();
            showUsernameToast();
        }
    }
    
    // ScreenCaptureManager.ScreenCaptureCallback methods
    @Override
    public void onScreenCapturerReady(VideoCapturer capturer) {
        peerConnectionManager.setVideoCapturer(capturer);
        peerConnectionManager.startLocalVideoCapture(localVideoView);
        
        if (userSessionManager.isCaller()) {
            createOffer();
        }
    }
    
    // PeerConnectionManager.PeerConnectionCallback methods
    @Override
    public void onIceCandidate(IceCandidate iceCandidate) {
        webSocketManager.sendIceCandidate(userSessionManager.getTargetUser(), iceCandidate);
    }
    
    @Override
    public void onAddStream(MediaStream mediaStream) {
        runOnUiThread(() -> {
            if (mediaStream.videoTracks.size() > 0) {
                mediaStream.videoTracks.get(0).addSink(remoteVideoView);
            }
        });
    }
    
    @Override
    public void onRemoveStream(MediaStream mediaStream) {
        // Handle stream removal if needed
    }
    
    // WebSocketManager.WebSocketCallback methods
    @Override
    public void onWebSocketOpen() {
        Log.d(TAG, "WebSocket opened");
    }
    
    @Override
    public void onWebSocketMessage(String type, String fromUser, JSONObject data) {
        switch (type) {
            case "call_start":
                handleIncomingCall(fromUser);
                break;
            case "offer":
                handleOffer(data);
                break;
            case "answer":
                handleAnswer(data);
                break;
            case "_ice":
                handleIceCandidate(data);
                break;
            case "hangup":
                hangup();
                break;
            case "call_back":
                try {
                    String msg = data.optString("msg", "");
                    if (msg.equals("1")) {
                        createOffer();
                    } else {
                        runOnUiThread(() -> Toast.makeText(this, "对方拒绝了通话", Toast.LENGTH_SHORT).show());
                        hangup();
                    }
                } catch (Exception e) {
                    Log.e(TAG, "Error handling call_back: " + e.getMessage());
                }
                break;
        }
    }
    
    @Override
    public void onWebSocketClose() {
        Log.d(TAG, "WebSocket closed");
    }
    
    @Override
    public void onWebSocketError(Exception ex) {
        Log.e(TAG, "WebSocket error: " + ex.getMessage());
        runOnUiThread(() -> Toast.makeText(this, "WebSocket 错误: " + ex.getMessage(), Toast.LENGTH_SHORT).show());
    }
    
    private void createOffer() {
        peerConnectionManager.createOffer(new SimpleSdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                peerConnectionManager.setLocalDescription(new SimpleSdpObserver(), sessionDescription);
                webSocketManager.sendOffer(userSessionManager.getTargetUser(), sessionDescription);
            }
        });
    }
    
    private void handleIncomingCall(String fromUser) {
        runOnUiThread(() -> {
            new android.app.AlertDialog.Builder(ShareScreen.this)
                    .setTitle("来电")
                    .setMessage(fromUser + "请求共享屏幕")
                    .setPositiveButton("接听", (dialog, which) -> {
                        userSessionManager.setTargetUser(fromUser);
                        userSessionManager.setIsCaller(false);
                        peerConnectionManager.createPeerConnection();
                        screenCaptureManager.requestScreenCapture();
                        webSocketManager.sendCallResponse(fromUser, true);
                    })
                    .setNegativeButton("拒绝", (dialog, which) -> {
                        webSocketManager.sendCallResponse(fromUser, false);
                    })
                    .show();
        });
    }
    
    private void handleOffer(JSONObject json) {
        try {
            SessionDescription offer = new SessionDescription(
                    SessionDescription.Type.OFFER,
                    json.getString("sdp"));
            
            peerConnectionManager.setRemoteDescription(new SimpleSdpObserver() {
                @Override
                public void onSetSuccess() {
                    peerConnectionManager.createAnswer(new SimpleSdpObserver() {
                        @Override
                        public void onCreateSuccess(SessionDescription sessionDescription) {
                            peerConnectionManager.setLocalDescription(new SimpleSdpObserver(), sessionDescription);
                            webSocketManager.sendAnswer(userSessionManager.getTargetUser(), sessionDescription);
                        }
                    });
                }
            }, offer);
        } catch (JSONException e) {
            Log.e(TAG, "Error handling offer: " + e.getMessage());
        }
    }
    
    private void handleAnswer(JSONObject json) {
        try {
            SessionDescription answer = new SessionDescription(
                    SessionDescription.Type.ANSWER,
                    json.getString("sdp")
            );
            peerConnectionManager.setRemoteDescription(new SimpleSdpObserver(), answer);
        } catch (JSONException e) {
            Log.e(TAG, "Error handling answer: " + e.getMessage());
        }
    }
    
    private void handleIceCandidate(JSONObject json) {
        try {
            IceCandidate candidate = new IceCandidate(
                    json.getString("sdpMid"),
                    json.getInt("sdpMLineIndex"),
                    json.getString("candidate")
            );
            peerConnectionManager.addIceCandidate(candidate);
        } catch (JSONException e) {
            Log.e(TAG, "Error handling ICE candidate: " + e.getMessage());
        }
    }
    
    private void hangup() {
        runOnUiThread(() -> {
            if (userSessionManager.getTargetUser() != null) {
                webSocketManager.sendHangup(userSessionManager.getTargetUser());
            }
            
            peerConnectionManager.stopCapture();
            peerConnectionManager.dispose();
            
            localVideoView.clearImage();
            remoteVideoView.clearImage();
            
            userSessionManager.clearSession();
        });
    }
    
    private void showUsernameToast() {
        runOnUiThread(() -> {
            Toast.makeText(this, "你的随机连接码为：" + userSessionManager.getUsername(), Toast.LENGTH_LONG).show();
        });
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        webSocketManager.close();
        peerConnectionManager.dispose();
        screenCaptureManager.unbindService();
        
        if (eglBase != null) {
            eglBase.release();
        }
    }
}